import { Options } from './options'
import define from 'rollup-plugin-define'
import { parse } from './parser'
import { generateDefines, generateDts } from './generate'
import { FilterPattern } from '@rollup/pluginutils'
import { pickBy } from 'lodash-es'

export interface PluginOptions extends Options {
  include?: FilterPattern
  exclude?: FilterPattern
  /**
   * @default 'src/typings/env.d.ts'
   */
  outputDts?: string
  /**
   * support 'global', 'process.env', 'import.meta.env'
   * @default ['global','process.env','import.meta.env']
   */
  dtsTarget?: string[]
  onDotenvGenerate?: (env: Record<string, any>) => void | Record<string, any>
}

export default function dotenv(options: PluginOptions = {}) {
  options.outputDts = options.outputDts || 'src/typings/env.d.ts'
  options.dtsTarget = options.dtsTarget || ['global', 'process.env', 'import.meta.env']
  const { include, exclude } = options

  let env = parse(options)
  env = options.onDotenvGenerate?.(env) || env
  generateDts(env, options)

  const defines = pickBy(generateDefines(env), (_, key) => !key.includes('['))
  const replacements: Record<string, string> = {}

  for (const target of options.dtsTarget!) {
    switch (target) {
      case 'global':
        Object.assign(replacements, defines)
        break
      default:
        Object.assign(
          replacements,
          Object.fromEntries(
            Object.entries(defines).map((key, value) => [`${target}.${key}`, value])
          )
        )
        break
    }
  }

  return define({
    include,
    exclude,
    replacements,
  })
}
